partList = [] #粒子集合
partNums = 6000 #粒子数量
noiseScale = 800  #噪声比例，放在分母的参数调整噪声值的读取
noiseStrenth = 10  #噪声强度，调整噪声值变化剧烈程度（因为noise返回值为0-1）
radius = 250#半径大小

def setup():
    size(1000,1000) #画布大小1000x1000
    noStroke()  #绘制不描边
    blendMode(ADD) #混色模式ADD
    colorMode(HSB,360,100,100,60) #颜色模式HSB
    initialize() #初始化
    
def draw():
    for p in partList:  #遍历partList里的每个粒子
        p.move()  #粒子移动
        p.show()  #绘制粒子
        
def newParticles():
    del partList[:]  #先清空列表
    for i in range(partNums):  #循环生成partNums个粒子
        partList.append(Particle())
        
def mousePressed():  #如果鼠标按下
    initialize()  #初始化
    
def keyPressed():  #按下s键保存图片到代码目录
    if key == 's':
        saveFrame("####.png")  #保存的格式是"####.png"
    
def initialize():
    background(0) #设置背景色
    newParticles()  #重置粒子容器
        
#----------------------------------------

class Particle:
    count = 0 #绘制次数
    
    def __init__(self):
        self.pos = PVector(random(width),random(height))  #随机生成坐标
        
    def move(self):
        if self.inCircle():  #如果在圆内
            #三维noise()计算角度。除了x、y二维外，多一个次数维度，相当于随时间变化
            self.angle = noise(self.pos.x/noiseScale , self.pos.y/noiseScale , self.count) * noiseStrenth
        else:  #否则
            #根据x、y坐标二维noise()，计算角度
            self.angle = noise(self.pos.x/noiseScale , self.pos.y/noiseScale ) * noiseStrenth
        self.pos.x += cos(self.angle) #根据横向移动
        self.pos.y += sin(self.angle) #根据纵向移动
        if self.pos.x>width or self.pos.x<0 or self.pos.y>height or self.pos.y<0 : #如果超出画布边界
            self.hitWall() #粒子撞墙
        self.count += 0.008
        
    def show(self):
        #角度一维noise()映射色相
        fill( map(noise(self.angle),0,1,140,360), 60 , 60 ,15)  
        # fill(map(noise(self.angle), 0, 1, 140, 300), 60, 60, 15);  #蓝
        # fill(map(noise(self.angle), 0, 1, 0, 100), 60, 60, 15);  #金
        # fill(map(noise(self.angle), 0, 1, 210, 360), 60, 60, 15);#紫
        # fill(map(noise(self.angle), 0, 1, 0, 55), 87, 75, 15); #红
        # fill(map(noise(self.angle), 0, 1, 0, 300), 60, 60, 15); #绿
        circle(self.pos.x, self.pos.y, 1) #在粒子所在坐标画圆
    
    def hitWall(self):
        self.pos = PVector(random(width),random(height))  #粒子位置重新生成
        
    def inCircle(self):
        ret = False  #默认不在圆内，返回值ret为False
        if( dist(self.pos.x , self.pos.y , width/2 , height/2) < radius ): #如果圆心距小于中心圆半径
            ret = True  #则在圆内，返回值变为True
        return ret #返回ret
